﻿using System;
using System.Collections.Generic;
using System.IO;
using Kent.Boogaart.Gauntlet.Diagnostics;
using Kent.Boogaart.HelperTrinity;

namespace Kent.Boogaart.Gauntlet
{
	/// <summary>
	/// Base class for a Gauntlet context, which is passed through the generation process.
	/// </summary>
	/// <remarks>
	/// <para>
	/// An instance of this class is passed through the generation pipeline. It provides access to a log and a state bag, as well as
	/// general information about the generation operation.
	/// </para>
	/// </remarks>
	public class Context
	{
		private readonly IDictionary<string, object> _state;
		private ILog _log;

		/// <summary>
		/// Gets or sets an <see cref="ILog"/> implementation that can be used to log information throughout the generation process.
		/// </summary>
		/// <remarks>
		/// <para>
		/// This property can only be set once. Any subsequent attempt to set the property will result in an exception.
		/// </para>
		/// </remarks>
		public ILog Log
		{
			get
			{
				if (_log == null)
				{
					//default to a TraceSourceLog if no other specified
					_log = new TraceSourceLog("Kent.Boogaart.Gauntlet");
				}

				return _log;
			}
			set
			{
				ExceptionHelper.ThrowIf(_log != null, "LogAlreadySet");
				_log = value;
			}
		}

		/// <summary>
		/// Gets or sets the input file for the generation process.
		/// </summary>
		public FileInfo InputFile { get; internal set; }

		/// <summary>
		/// Gets or sets the output file for the generation process.
		/// </summary>
		public FileInfo OutputFile { get; internal set; }

		/// <summary>
		/// Gets or sets the template file for the generation process.
		/// </summary>
		public FileInfo TemplateFile { get; internal set; }

		/// <summary>
		/// Gets a timestamp indicating when the generation process was started.
		/// </summary>
		public DateTime Timestamp { get; internal set; }

		/// <summary>
		/// Gets a state bag for the generation process.
		/// </summary>
		public IDictionary<string, object> State
		{
			get
			{
				return _state;
			}
		}

		/// <summary>
		/// Constructs an instance of the <c>Context</c> class.
		/// </summary>
		public Context()
		{
			_state = new Dictionary<string, object>();
		}
	}
}